<template>
	<view class="tui-numberbox">
		<view
			class="tui-numbox-icon tui-icon-reduce "
			:class="[disabled || min >= inputValue ? 'tui-disabled' : '']"
			@tap="reduce"
			:style="{ color: iconColor, fontSize: iconSize + 'rpx' }"
		></view>
		<input
			type="number"
			v-model="inputValue"
			:disabled="disabled"
			@blur="blur"
			class="tui-num-input"
			:style="{ color: color, fontSize: size + 'rpx', backgroundColor: backgroundColor, height: height + 'rpx', minHeight: height + 'rpx', width: width + 'rpx' }"
		/>
		<view
			class="tui-numbox-icon tui-icon-plus"
			:class="[disabled || inputValue >= max ? 'tui-disabled' : '']"
			@tap="plus"
			:style="{ color: iconColor, fontSize: iconSize + 'rpx' }"
		></view>
	</view>
</template>

<script setup>
import { ref, reactive, toRefs, getCurrentInstance, onBeforeMount, onMounted } from 'vue'

const emit = defineEmits(['change'])

const props = defineProps({
	value: {
		type: [Number, String],
		default: 1
	},
	//最小值
	min: {
		type: Number,
		default: 1
	},
	//最大值
	max: {
		type: Number,
		default: 99
	},
	//迈步大小 1 1.1 10...
	step: {
		type: Number,
		default: 1
	},
	//是否禁用操作
	disabled: {
		type: Boolean,
		default: false
	},
	//加减图标大小 rpx
	iconSize: {
		type: Number,
		default: 26
	},
	iconColor: {
		type: String,
		default: '#666666'
	},
	//input 高度
	height: {
		type: Number,
		default: 42
	},
	//input 宽度
	width: {
		type: Number,
		default: 80
	},
	size: {
		type: Number,
		default: 28
	},
	//input 背景颜色
	backgroundColor: {
		type: String,
		default: '#F5F5F5'
	},
	//input 字体颜色
	color: {
		type: String,
		default: '#333'
	},
	//索引值，列表中使用
	index: {
		type: [Number, String],
		default: 0
	},
	//自定义参数
	custom: {
		type: [Number, String],
		default: 0
	}
})

let inputValue = ref(0)

const state = reactive({
	isFixed: false
})

watch(
	() => props.value,
	nVal => {
		inputValue.value = +nVal
	}
)

onBeforeMount(() => {
	inputValue = +props.value
})

onMounted(() => {})

const getLen = (val, step) => {
	let len = 0
	let lenVal = 0
	//浮点型
	if (!Number.isInteger(step)) {
		len = (step + '').split('.')[1].length
	}
	//浮点型
	if (!Number.isInteger(val)) {
		lenVal = (val + '').split('.')[1].length
	}
	return Math.max(len, lenVal)
}

const getScale = (val, step) => {
	let scale = 1
	let scaleVal = 1
	//浮点型
	if (!Number.isInteger(step)) {
		scale = Math.pow(10, (step + '').split('.')[1].length)
	}
	//浮点型
	if (!Number.isInteger(val)) {
		scaleVal = Math.pow(10, (val + '').split('.')[1].length)
	}
	return Math.max(scale, scaleVal)
}

const plus = () => {
	calcNum('plus')
}

const reduce = () => {
	calcNum('reduce')
}

const toFixed = (num, s) => {
	let times = Math.pow(10, s)
	let des = num * times + 0.5
	des = parseInt(des, 10) / times
	return des
}

const calcNum = type => {
	if (props.disabled || (inputValue.value === props.min && type === 'reduce') || (inputValue.value === props.max && type === 'plus')) {
		return
	}
	const scale = getScale(Number(inputValue.value), Number(props.step))
	let len = getLen(Number(inputValue.value), Number(props.step))
	let num = Number(inputValue.value) * scale
	let step = props.step * scale
	if (type === 'reduce') {
		num -= step
	} else if (type === 'plus') {
		num += step
	}
	let value = toFixed(num / scale, len)
	if (value < props.min) {
		value = props.min
	} else if (value > props.max) {
		value = props.max
	}
	handleChange(value, type)
}

const blur = e => {
	let value = e.detail.value
	if (value) {
		if (~value.indexOf('.') && !Number.isInteger(props.step) && !Number.isInteger(Number(value))) {
			value = value.split('.')[0]
		}
		value = Number(value)
		if (value > props.max) {
			value = props.max
		} else if (value < props.min) {
			value = props.min
		}
	} else {
		value = props.min
	}
	if ((value == props.value && value != inputValue.value) || !e.detail.value) {
		inputValue.value = value
	}
	handleChange(value, 'blur')
}

const handleChange = (value, type) => {
	if (props.disabled) return
	emit('change', {
		value: Number(value),
		type: type,
		index: props.index,
		custom: props.custom
	})
}
</script>

<style lang="scss" scoped>
@font-face {
	font-family: 'numberbox';
	src: url(data:application/font-woff;charset=utf-8;base64,d09GRgABAAAAAASQAA0AAAAABtwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABGRlRNAAAEdAAAABoAAAAciBpnRUdERUYAAARUAAAAHgAAAB4AKQALT1MvMgAAAZwAAABDAAAAVjxzSINjbWFwAAAB9AAAAEYAAAFK5zLpOGdhc3AAAARMAAAACAAAAAj//wADZ2x5ZgAAAkgAAACHAAAAnIfIEjxoZWFkAAABMAAAAC8AAAA2FZWEOWhoZWEAAAFgAAAAHAAAACQH3gOFaG10eAAAAeAAAAARAAAAEgwAAAFsb2NhAAACPAAAAAwAAAAMADAATm1heHAAAAF8AAAAHwAAACABEAAobmFtZQAAAtAAAAFJAAACiCnmEVVwb3N0AAAEHAAAAC0AAABV/+8iFXjaY2BkYGAA4gVmC5Tj+W2+MnCzMIDATWsFOQT9v5GFgbkeyOVgYAKJAgDrogf+AHjaY2BkYGBu+N/AEMPCAAJAkpEBFbAAAEcKAm142mNgZGBgYGWQYQDRDAxMQMwFhAwM/8F8BgALpAE5AHjaY2BkYWCcwMDKwMDUyXSGgYGhH0IzvmYwYuQAijKwMjNgBQFprikMDs9Yn01kbvjfwBDD3MDQABRmBMkBAOXpDHEAeNpjYYAAFghmZGAAAACdAA4AAAB42mNgYGBmgGAZBkYGEHAB8hjBfBYGDSDNBqQZGZiesT6b+P8/AwOElvwnWQxVDwSMbAxwDiMTkGBiQAWMDMMeAABRZwszAAAAAAAAAAAAAAAwAE542iWKQQrCMBBF5xNpd0pQ7EIoTEnahSCTUNqdWz2A9TrieXKeXCc1qcPn/zfzh0BYv2pVH7oQgbvqdG5Yt/DTrNlPYz+wHvuuqhFSME4sFshTgKUsKfhH5lg8BSul3i5bS3mQdd0RIh2IjnvUrkXDd8zuhuFt86tY9fonIsSYgsXpB+cCGosAeNp9kD1OAzEQhZ/zByQSQiCoXVEA2vyUKRMp9Ailo0g23pBo1155nUg5AS0VB6DlGByAGyDRcgpelkmTImvt6PObmeexAZzjGwr/3yXuhBWO8ShcwREy4Sr1F+Ea+V24jhY+hRvUf4SbuFUD4RYu1BsdVO2Eu5vSbcsKZxgIV3CKJ+Eq9ZVwjfwqXMcVPoQb1L+EmxjjV7iFa2WpDOFhMEFgnEFjig3jAjEcLJIyBtahOfRmEsxMTzd6ETubOBso71dilwMeaDnngCntPbdmvkon/mDLgdSYbh4FS7YpjS4idCgbXyyc1d2oc7D9nu22tNi/a4E1x+xRDWzU/D3bM9JIbAyvkJI18jK3pBJTj2hrrPG7ZynW814IiU68y/SIx5o0dTr3bmniwOLn8owcfbS5kj33qBw+Y1kIeb/dTsQgil2GP5PYcRkAAAB42mNgYoAALjDJyIAOWMGiTIxMjMwiWZmJQJRXVQoigTgjMd9QGIsgAFDsEBsAAAAAAAAB//8AAgABAAAADAAAABYAAAACAAEAAwAEAAEABAAAAAIAAAAAeNpjYGBgZACCq0vUOUD0TWsFORgNADPBBE4AAA==)
		format('woff');
	font-weight: normal;
	font-style: normal;
}

.tui-numbox-icon {
	font-family: 'numberbox' !important;
	font-style: normal;
	-webkit-font-smoothing: antialiased;
	-moz-osx-font-smoothing: grayscale;
	padding: 10rpx;
}

.tui-icon-reduce:before {
	content: '\e691';
}

.tui-icon-plus:before {
	content: '\e605';
}

.tui-numberbox {
	display: -webkit-inline-flex;
	display: inline-flex;
	align-items: center;
}

.tui-num-input {
	text-align: center;
	margin: 0 12rpx;
	font-weight: 400;
}

.tui-disabled {
	color: #ededed !important;
}
</style>
